<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>所有函数的公共区域prototype</title>
</head>
<body>
<script>
    /*原型prototype 我们所创建的每一个函数，解析器都会向函数中添加一个属性prototype prototype就是原型对象
    *       如果函数作为普通函数调用prototype没有任何意义
    *               作为构造函数调用时，它所创建的对象中都会有一个隐含的属性指向构造函数的对象
    *               我们可以通过__proto__(proto前后各2个下划线)来访问该属性
    *        原型对象就相当于一个公共区域,所有同一类的实例都可以访问到这个对象
    *           我们可以将对象中共有的内容，统一设置在里面原型对象中
    *       以后我们创建构造函数时，可以将这些对象共有的属性和方法，统一添加到构造函数的原型对象中
    *      这样不用分别为每一个对象添加，也不会影响全局作用域,就可以使每个对象都具有这些属性和方法
    * 使用in检查对象中是否含有某个属性时,如果对象中没有原型中有,也会返回true
    *可以使用对象的hasOwnProperty()来检查对象自身是否含有该属性
    *原型对象也是对象，所以它也有原型，当我们使用一个对象的属性或方法时，会先在自身中寻找，
    *   自身如果有 则直接使用，如果没有则去原型对象中寻找，如果原型对象中有 则使用
    * 如果没有则去原型中寻找，知道找到Object对象模型
    *   Object对象的原型没有原型。如果在Object中依然没有找到.则返回undefined
    *
    * */
    function Person() {

    }
    function MyClass() {

    }
    //向MyClass的原型对象中添加a
    MyClass.prototype.a=123;
    //向原型对象添加方法
    MyClass.prototype.sayHello=function () {
        alert("hello");
    };
    var mc=new MyClass();
    var mc1=new MyClass();

    // console.log(Person.prototype);
    // console.log(MyClass.prototype);
    console.log(mc.__proto__==MyClass.prototype);//true
    console.log(mc.a);//返回123
    console.log(mc.sayHello);

    //向Person的原型对象中添加name属性
    Person.prototype.name="我是原型中的名字";
    var per=new Person();
    per.age=55;
    console.log(per.name);
    console.log("name" in per);//true 使用in检查对象中是否含有某个属性时,如果对象中没有原型中有,也会返回true
    //可以使用对象的hasOwnProperty()来检查对象自身是否含有该属性
    console.log(per.hasOwnProperty("name"));//false 原型对象中的属性
    console.log(per.hasOwnProperty("age"));//true在自身中添加的属性
    console.log(per.hasOwnProperty("hasOwnProperty"));//false
    console.log(per.__proto__.hasOwnProperty("hasOwnProperty"));//false
    console.log(per.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));//true "hasOwnProperty"在原型对象的原型对象中
    console.log(per.__proto__.__proto__.__proto__);//null 说明不用在往上找了 没有了
</script>
</body>
</html>